package com.chatai.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api/file")
public class FileController {
    
    // 使用系统临时目录作为文件上传位置，这是最安全的方式
    private String uploadDir = System.getProperty("java.io.tmpdir") + File.separator + "chat-uploads";
    
    // 仍然保留配置项功能，但提供更安全的默认值
    @Value("${file.upload-dir:}")
    public void setUploadDir(String configuredDir) {
        if (configuredDir != null && !configuredDir.trim().isEmpty()) {
            this.uploadDir = configuredDir;
        }
    }
    
    /**
     * 上传文件接口
     * @param file 上传的文件
     * @return 文件访问URL
     */
    @PostMapping("/upload")
    public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 检查文件是否为空
            if (file == null || file.isEmpty()) {
                return ResponseEntity.badRequest().body("File is empty or null");
            }
            
            // 日志：记录收到的文件信息
            System.out.println("收到文件上传请求");
            System.out.println("文件名: " + file.getOriginalFilename());
            System.out.println("文件大小: " + file.getSize() + " 字节");
            System.out.println("配置的上传目录: " + uploadDir);

            // 确保上传目录存在，使用标准的Path API
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                System.out.println("创建上传目录: " + uploadDir);
                try {
                    Files.createDirectories(uploadPath);
                    System.out.println("上传目录创建成功");
                } catch (IOException e) {
                    System.out.println("创建上传目录失败: " + e.getMessage());
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .body("Failed to create upload directory: " + e.getMessage());
                }
            }
            
            // 检查目录是否可写
            if (!Files.isWritable(uploadPath)) {
                System.out.println("警告: 上传目录不可写: " + uploadDir);
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Server error: Upload directory is not writable");
            }

            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
            }
            String filename = UUID.randomUUID().toString() + extension;
            
            // 目标文件路径
            Path targetLocation = uploadPath.resolve(filename);
            System.out.println("目标文件路径: " + targetLocation.toString());

            try {
                // 验证输入流是否有效
                try (InputStream inputStream = file.getInputStream()) {
                    if (inputStream.available() <= 0) {
                        System.out.println("错误: 文件输入流为空");
                        return ResponseEntity.badRequest().body("File content is empty");
                    }
                    
                    // 保存文件
                    Files.copy(inputStream, targetLocation, StandardCopyOption.REPLACE_EXISTING);
                }
                
                System.out.println("文件保存成功");
                
                // 验证文件是否真的保存成功
                if (!Files.exists(targetLocation)) {
                    System.out.println("错误: 文件保存后不存在");
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .body("Failed to save file: File not found after save");
                }
            } catch (IOException e) {
                System.out.println("文件保存失败: " + e.getMessage());
                e.printStackTrace();
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Failed to save file: " + e.getMessage());
            }

            // 返回文件URL
            String fileUrl = "/api/file/download/" + filename;
            System.out.println("返回文件URL: " + fileUrl);
            
            Map<String, String> response = new HashMap<>();
            response.put("fileUrl", fileUrl);
            response.put("filename", originalFilename);
            return ResponseEntity.ok().body(response);
        } catch (org.springframework.web.multipart.MultipartException e) {
            // 专门处理多部分请求解析异常
            System.out.println("多部分请求解析失败: " + e.getMessage());
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body("Invalid file upload request format. Please use multipart/form-data correctly.");
        } catch (Exception e) {
            // 详细记录异常信息
            System.out.println("文件上传异常: " + e.getMessage());
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Failed to upload file: " + e.getMessage());
        }
    }
    
    /**
     * 下载文件接口
     * @param filename 文件名
     * @return 文件内容
     */
    @GetMapping("/download/{filename}")
    public ResponseEntity<?> downloadFile(@PathVariable String filename) {
        try {
            Path filePath = Paths.get(uploadDir, filename);
            
            // 检查文件是否存在
            if (!Files.exists(filePath)) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body("File not found: " + filename);
            }
            
            // 读取文件内容
            byte[] fileContent = Files.readAllBytes(filePath);
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", filename);
            headers.setContentLength(fileContent.length);
            
            return ResponseEntity.ok()
                .headers(headers)
                .body(fileContent);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Failed to download file: " + e.getMessage());
        }
    }
}